home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / pattern.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  15KB  |  537 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/IntrinsicP.h>
  16. #include <X11/Shell.h>
  17. #include <X11/StringDefs.h>
  18. #include <X11/Xaw/Box.h>
  19. #include <X11/Xaw/Form.h>
  20. #include <X11/Xaw/Scrollbar.h>
  21. #include <X11/Xaw/Viewport.h>
  22. #include <X11/Xaw/Command.h>
  23. #include <X11/CoreP.h>
  24. #include <X11/Xaw/ToggleP.h>
  25. #include <X11/cursorfont.h>
  26. #include <stdio.h>
  27. #include "Colormap.h"
  28. #include "Paint.h"
  29. #include "palette.h"
  30. #include "xpaint.h"
  31. #include "menu.h"
  32. #include "misc.h"
  33. #include "cutCopyPaste.h"
  34. #include "image.h"
  35. #include "text.h"
  36.  
  37. #ifndef NOSTDHDRS
  38. #include <stdlib.h>
  39. #include <unistd.h>
  40. #endif
  41.  
  42. static PaintMenuItem    fileMenu[] = {
  43.     MI_SIMPLE("read"),
  44.     MI_SIMPLE("save"),
  45.     MI_SIMPLE("close"),
  46. };
  47. static PaintMenuItem    editMenu[] = {
  48.     MI_SIMPLE("undo"),
  49.     MI_SEPERATOR(),
  50.     MI_SIMPLE("cut"),
  51.     MI_SIMPLE("copy"),
  52.     MI_SIMPLE("paste"),
  53.     MI_SIMPLE("clear"),
  54.     MI_SEPERATOR(),
  55.     MI_SIMPLE("dup"),
  56.     MI_SIMPLE("all"),
  57. };
  58. static PaintMenuItem    sizeMenu[] = {
  59. #define SZ_N1    0
  60.     MI_FLAG("16x16", MF_CHECK|MF_GROUP1),
  61. #define SZ_N2    1
  62.     MI_FLAG("24x24", MF_CHECK|MF_GROUP1),
  63. #define SZ_N3    2
  64.     MI_FLAG("32x32", MF_CHECK|MF_GROUP1),
  65. #define SZ_N4    3
  66.     MI_FLAG("48x48", MF_CHECK|MF_GROUP1),
  67. #define SZ_N5    4
  68.     MI_FLAG("64x64", MF_CHECK|MF_GROUP1),
  69.     MI_SEPERATOR(),
  70. #define SZ_N6    6
  71.     MI_FLAG("other", MF_CHECK|MF_GROUP1),
  72. };
  73. static PaintMenuItem    imageMenu[] = {
  74.     MI_FLAG("grid", MF_CHECK),
  75. };
  76. static PaintMenuItem    helpMenu[] = {
  77.     MI_SIMPLECB("help", HelpDialog, "canvas.patBox.pattern"),
  78. };
  79. static PaintMenuBar     menuBar[] = {
  80.         { None, "file",  XtNumber(fileMenu),  fileMenu },
  81.         { None, "edit",  XtNumber(editMenu),  editMenu },
  82.         { None, "size",  XtNumber(sizeMenu),  sizeMenu },
  83.         { None, "image", XtNumber(imageMenu), imageMenu },
  84.         { None, "help",  XtNumber(helpMenu),  helpMenu },
  85. };
  86.  
  87. #define    RED    1
  88. #define    GREEN    2
  89. #define    BLUE    3
  90.  
  91. Widget ColorPickerPalette(Widget, Palette *, Pixel *);
  92.  
  93. typedef struct {
  94.     int    add;
  95.     Pixmap    pix;
  96.     void    *iconList;
  97.     Widget    fat, norm, paint;
  98.     Widget    cpick, color;
  99.     Widget    curCheck;
  100.     Widget    sizeChecks[XtNumber(sizeMenu) - 1];
  101.     Palette    *map;
  102. } LocalInfo;
  103.  
  104. static void activePixel(LocalInfo *l, Pixel p)
  105. {
  106.     if (l->color != None)
  107.         XtVaSetValues(l->color, XtNcolor, p, NULL);
  108.     XtVaSetValues(l->fat, XtNforeground, p, 
  109.                   XtNlineForeground, p,
  110.                   NULL);
  111.     if (l->cpick != None)
  112.         ColorPickerSetPixel(l->cpick, p);
  113.     PaletteSetInvalid(l->map, p);
  114. }
  115.  
  116. static void cpickCallback(Widget w, LocalInfo *l, Pixel p)
  117. {
  118.     activePixel(l, p);
  119. }
  120.  
  121. static void colorCallback(Widget w, LocalInfo *l, XColor *color)
  122. {
  123.     activePixel(l, color->pixel);
  124. }
  125.  
  126. static void matchCallback(Widget w, LocalInfo *l, XtPointer junk)
  127. {
  128.     Colormap        cmap;
  129.     Pixel            p;
  130.  
  131.     DoGrabPixel(w, &p, &cmap);
  132.  
  133.     if (l->map->cmap == cmap) {
  134.         activePixel(l, p);
  135.     } else {
  136.         XColor    col;
  137.  
  138.         col.flags = DoRed|DoGreen|DoBlue;
  139.         col.pixel = p;
  140.         XQueryColor(XtDisplay(w), cmap, &col);
  141.         if (PaletteLookupColor(l->map, &col, &p)) {
  142.             activePixel(l, p);
  143.         } else {
  144.             Notice(w,"Selected color is from a different colormap,\nwith no matching color on this colormap");
  145.         }
  146.     }
  147. }
  148.  
  149.  
  150. static void grabCallback(Widget w, XtPointer infoArg, XtPointer junk2)
  151. {
  152.     LocalInfo        *info = (LocalInfo *)infoArg;
  153.     Image            *image;
  154.     Colormap        cmap;
  155.     Pixmap            pix;
  156.     int            grabW, grabH;
  157.  
  158.     XtVaGetValues(info->fat, XtNdrawWidth, &grabW, 
  159.                  XtNdrawHeight, &grabH,
  160.                  NULL);
  161.  
  162.     image = (Image*)DoGrabImage(w, grabW, grabH);
  163.  
  164.     XtVaGetValues(info->paint, XtNcolormap, &cmap, NULL);
  165.     pix = None;
  166.     if (ImageToPixmapCmap(image, info->fat, &pix, cmap))
  167.         PwPutPixmap(info->fat, pix);
  168. }
  169.  
  170. static void closeCallback(Widget w, XtPointer infoArg, XtPointer junk2)
  171. {
  172.     LocalInfo    *info = (LocalInfo *)infoArg;
  173.  
  174.     XtDestroyWidget(GetShell(info->fat));
  175.     StateShellBusy(info->paint, False);
  176.     XtFree((XtPointer)info);
  177. }
  178. static void buttonCallback(Widget w, XtPointer infoArg, XtPointer junk2)
  179. {
  180.     LocalInfo    *info = (LocalInfo *)infoArg;
  181.     Pixmap        pix;
  182.     Widget        icon;
  183.     XtPointer    data;
  184.  
  185.     if (info != NULL) {
  186.         void    *pi = XawToggleGetCurrent(info->iconList);
  187.         PwRegionFinish(info->fat, True);
  188.         PwGetPixmap(info->fat, &pix, NULL, NULL);
  189.  
  190.         if (info->add) {
  191.             icon = AddPatternInfo(pi, pix, 0);
  192.  
  193. #if 0
  194.             XtVaGetValues(icon, XtNradioData, &data, NULL);
  195.  
  196.             XawToggleSetCurrent(icon, data);
  197. #endif
  198.         } else {
  199.             ChangePattern(pi, pix);
  200.         }
  201.  
  202. #if 0
  203.         XtVaSetValues(info->paint, XtNpattern, pix, NULL);
  204. #endif
  205.         StateShellBusy(info->paint, False);
  206.         XtFree((XtPointer)info);
  207.     }
  208.     XtDestroyWidget(GetShell(w));
  209. }
  210. static void readFileCallback(Widget paint, XtPointer fileArg, XtPointer imageArg)
  211. {
  212.     Image        *image = (Image *)imageArg;
  213.     Pixmap        pix;
  214.     Colormap    cmap;
  215.  
  216.     /*  XXX - allocating a new colormap! */
  217.     if (ImageToPixmap(image, paint, &pix, &cmap)) {
  218.         XtVaSetValues(paint, XtNcolormap, cmap, NULL);
  219.         PwPutPixmap(paint, pix);
  220.         return;
  221.     }
  222. }
  223. static void readCallback(Widget w, XtPointer paint, XtPointer junk)
  224. {
  225.     GetFileName((Widget)paint, False, NULL, readFileCallback, NULL);
  226. }
  227.  
  228. static void cac(LocalInfo *info, int inW, int inH)
  229. {
  230.     int        width,height,i;
  231.     String        lbl;
  232.  
  233.     for (i = 0; i < XtNumber(info->sizeChecks); i++) {
  234.         Widget    w = info->sizeChecks[i];
  235.         XtVaGetValues(w, XtNlabel, &lbl, NULL);
  236.         width = -1;
  237.         height = -1;
  238.         sscanf(lbl, "%dx%d", &width, &height);
  239.          if (width <= 0 || height <= 0 || (width == inW && height == inH)) {
  240.             MenuCheckItem(info->curCheck = w, True);
  241.             break;
  242.         }
  243.     }
  244. }
  245. static void sizeOkChoiceCallback(Widget w, LocalInfo *l, TextPromptInfo *info)
  246. {
  247.     int    width  = atoi(info->prompts[0].rstr);
  248.     int    height = atoi(info->prompts[1].rstr);
  249.  
  250.     if (width <= 0 || height <= 0) {
  251.         Notice(w, "Invalid width or height,\nmust be greater than 0");
  252.     } else if (width > 128 || height > 128) {
  253.         Notice(w, "Invalid width or height,\nmust be less than 129");
  254.     } else {
  255.         XtVaSetValues(l->fat, XtNdrawWidth, width,
  256.                       XtNdrawHeight, height,
  257.                       NULL);
  258.         MenuCheckItem(l->curCheck, False);
  259.         l->curCheck = None;
  260.         cac(l, width, height);
  261.     }
  262. }
  263. static void sizeChoiceCallback(Widget w, XtPointer larg, XtPointer junk)
  264. {
  265.     static TextPromptInfo        info;
  266.     static struct textPromptInfo    values[3];
  267.     char                bufA[16], bufB[16];
  268.     int                width, height;
  269.     LocalInfo            *l = (LocalInfo*)larg;
  270.  
  271.     XtVaGetValues(l->fat, XtNdrawWidth, &width,
  272.                   XtNdrawHeight, &height,
  273.                   NULL);
  274.  
  275.     info.prompts = values;
  276.     info.nprompt = 2;
  277.     info.title   = "Enter the desired pattern size:";
  278.     
  279.     values[0].prompt = "Width:";
  280.     values[0].str    = bufA;
  281.     values[0].len    = 4;
  282.     values[1].prompt = "Height:";
  283.     values[1].str    = bufB;
  284.     values[1].len    = 4;
  285.  
  286.     sprintf(bufA, "%d", width);
  287.     sprintf(bufB, "%d", height);
  288.  
  289.     TextPrompt(w, "sizeselect", &info, (XtCallbackProc)sizeOkChoiceCallback, NULL, larg);
  290. }
  291. static void sizeCallback(Widget w, XtPointer larg, XtPointer junk)
  292. {
  293.     LocalInfo    *l = (LocalInfo*)larg;
  294.     int        width,height;
  295.     String        lbl;
  296.  
  297.     if (l->curCheck == w) 
  298.         return;
  299.  
  300.     XtVaGetValues(w, XtNlabel, &lbl, NULL);
  301.     width = -1;
  302.     height = -1;
  303.     sscanf(lbl, "%dx%d", &width, &height);
  304.     if (width <= 0 || height <= 0 || width >= 256 || height >= 256) {
  305.         Notice(w, "Invalid width/height specification must be between 0..256");
  306.         return;
  307.     }
  308.  
  309.     MenuCheckItem(l->curCheck = w, True);
  310.  
  311.     /*
  312.     **  Just change the size, no OK
  313.     */
  314.     XtVaSetValues(l->fat, XtNdrawWidth, width,
  315.                   XtNdrawHeight, height,
  316.                   NULL);
  317.     XtVaSetValues(l->norm, XtNdrawWidth, width,
  318.                    XtNdrawHeight, height,
  319.                    NULL);
  320. }
  321. static void gridCallback(Widget w, XtPointer larg, XtPointer junk)
  322. {
  323.     LocalInfo    *l = (LocalInfo*)larg;
  324.     Boolean        v;
  325.  
  326.     XtVaGetValues(l->fat, XtNgrid, &v, NULL);
  327.     v = !v;
  328.     XtVaSetValues(l->fat, XtNgrid, v, NULL);
  329.  
  330.     MenuCheckItem(w, v);
  331. }
  332.  
  333. void PatternEdit(Widget w, Pixmap pix, Widget button)
  334. {
  335.     Widget        shell, form, topf, norm, box, vp;
  336.     Widget        color, fat, bar, cpick;
  337.     Widget        okButton, cancelButton, grabButton, matchButton;
  338.     Colormap    cmap;
  339.     Pixel        pval = WhitePixelOfScreen(XtScreen(w));
  340.     LocalInfo    *info = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  341.     Palette        *map;
  342.     int        width, height;
  343.     Position    x, y;
  344.  
  345.     info->paint    = w;
  346.     info->add      = (pix == None);
  347.     info->iconList = button;
  348.  
  349.     StateShellBusy(w, True);
  350.     XtVaGetValues(GetShell(w), XtNcolormap, &cmap, XtNx, &x, XtNy, &y, NULL);
  351.     info->map = map = PaletteFind(w, cmap);
  352.  
  353.     shell = XtVaCreatePopupShell("pattern", transientShellWidgetClass, GetShell(w),
  354.                 XtNcolormap, cmap,
  355.                 XtNx, x + 24,
  356.                 XtNy, y + 24,
  357.                 NULL);
  358.     PaletteAddUser(map, shell);
  359.  
  360.     topf  = XtVaCreateManagedWidget("form", formWidgetClass, shell, 
  361.             NULL);
  362.  
  363.     bar   = MenuBarCreate(topf, XtNumber(menuBar), menuBar);
  364.  
  365.     form  = XtVaCreateManagedWidget("box", formWidgetClass, topf, 
  366.             XtNfromVert, bar,
  367.             XtNtop, XtChainTop,
  368.             XtNbottom, XtChainBottom,
  369.             NULL);
  370.     vp   = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, 
  371.             XtNfromVert, bar,
  372.             XtNallowVert, True,
  373.             XtNallowHoriz, True,
  374.             XtNuseBottom, True,
  375.             XtNuseRight, True,
  376.             XtNleft, XtChainLeft,
  377.             XtNright, XtChainRight,
  378.             NULL);
  379.     box  = XtVaCreateManagedWidget("patternBox", boxWidgetClass, vp, 
  380.             XtNbackgroundPixmap, GetBackgroundPixmap(vp),
  381.             XtNorientation, XtorientHorizontal,
  382.             NULL);
  383.  
  384.     if (pix == None)
  385.         fat = XtVaCreateManagedWidget("paint", paintWidgetClass, box, 
  386.                 XtNpixmap, pix,
  387.                 XtNdrawWidth, 24,
  388.                 XtNdrawHeight, 24,
  389.                 XtNfillRule, FillSolid,
  390.                 NULL);
  391.     else
  392.         fat = XtVaCreateManagedWidget("paint", paintWidgetClass, box, 
  393.                 XtNpixmap, pix,
  394.                 XtNfillRule, FillSolid,
  395.                 NULL);
  396.     norm = XtVaCreateManagedWidget("norm", paintWidgetClass, box,
  397.                 XtNpaint, fat,
  398.                 XtNfillRule, FillSolid,
  399.                 XtNzoom, 1,
  400.                 NULL);
  401.     OperationSetPaint(fat);
  402.     ccpAddStdPopup(fat);
  403.  
  404.  
  405.     cpick = None;
  406.     if (!map->isMapped || !map->readonly || map->ncolors > 256)
  407.         cpick = ColorPickerPalette(form, map, &pval);
  408.     
  409.     if (map->isMapped) {
  410.         color = XtVaCreateManagedWidget("cedit", colormapWidgetClass, form, 
  411.                 XtNwidth, 256,
  412.                 XtNheight, 256,
  413.                 XtNcolormap, cmap,
  414.                 XtNfromHoriz, vp,
  415.                 XtNleft, XtChainRight,
  416.                 XtNright, XtChainRight,
  417.                 NULL);
  418.         if (cpick != None)
  419.             XtVaSetValues(cpick, XtNfromHoriz, color, 
  420.                          XtNleft, XtChainRight,
  421.                          NULL);
  422.         XtAddCallback(color, XtNcallback, 
  423.             (XtCallbackProc)colorCallback, (XtPointer)info);
  424.     } else {
  425.         color = None;
  426.         if (cpick != None) {
  427.             XtVaSetValues(cpick, XtNfromHoriz, vp,
  428.                          XtNleft, XtChainRight,
  429.                          XtNright, XtChainRight,
  430.                          NULL);
  431.             ColorPickerSetFunction(cpick, 
  432.                 (XtCallbackProc)cpickCallback, (XtPointer)info);
  433.         }
  434.     }
  435.  
  436.     info->cpick = cpick;
  437.     info->color = color;
  438.     info->fat    = fat;
  439.     info->norm   = norm;
  440.  
  441.     okButton = XtVaCreateManagedWidget("ok", 
  442.                 commandWidgetClass, topf,
  443.                 XtNfromVert, form,
  444.                 XtNtop, XtChainBottom,
  445.                 XtNbottom, XtChainBottom,
  446.                 XtNleft, XtChainLeft,
  447.                 XtNright, XtChainLeft,
  448.                 NULL);
  449.  
  450.     cancelButton = XtVaCreateManagedWidget("cancel", 
  451.                 commandWidgetClass, topf,
  452.                 XtNfromVert, form,
  453.                 XtNfromHoriz, okButton,
  454.                 XtNtop, XtChainBottom,
  455.                 XtNbottom, XtChainBottom,
  456.                 XtNleft, XtChainLeft,
  457.                 XtNright, XtChainLeft,
  458.                 NULL);
  459.     grabButton = XtVaCreateManagedWidget("grab", 
  460.                 commandWidgetClass, topf,
  461.                 XtNfromVert, form,
  462.                 XtNfromHoriz, cancelButton,
  463.                 XtNtop, XtChainBottom,
  464.                 XtNbottom, XtChainBottom,
  465.                 XtNleft, XtChainLeft,
  466.                 XtNright, XtChainLeft,
  467.                 NULL);
  468.     matchButton = XtVaCreateManagedWidget("lookup", 
  469.                 commandWidgetClass, topf,
  470.                 XtNfromVert, form,
  471.                 XtNfromHoriz, grabButton,
  472.                 XtNtop, XtChainBottom,
  473.                 XtNbottom, XtChainBottom,
  474.                 XtNleft, XtChainLeft,
  475.                 XtNright, XtChainLeft,
  476.                 NULL);
  477.  
  478.     ccpAddUndo(XtNameToWidget(bar, "edit.editMenu.undo"), fat);
  479.     ccpAddCut(XtNameToWidget(bar, "edit.editMenu.cut"), fat);
  480.     ccpAddCopy(XtNameToWidget(bar, "edit.editMenu.copy"), fat);
  481.     ccpAddPaste(XtNameToWidget(bar, "edit.editMenu.paste"), fat);
  482.     ccpAddClear(XtNameToWidget(bar, "edit.editMenu.clear"), fat);
  483.     ccpAddDuplicate(XtNameToWidget(bar, "edit.editMenu.dup"), fat);
  484.  
  485.     XtAddCallback(XtNameToWidget(bar, "edit.editMenu.all"),
  486.             XtNcallback, StdSelectAllCallback, (XtPointer)fat);
  487.  
  488.     XtAddCallback(XtNameToWidget(bar, "file.fileMenu.close"),
  489.             XtNcallback, closeCallback, (XtPointer)info);
  490.     XtAddCallback(XtNameToWidget(bar, "file.fileMenu.save"),
  491.             XtNcallback, StdSaveFile, (XtPointer)fat);
  492.     XtAddCallback(XtNameToWidget(bar, "file.fileMenu.read"),
  493.             XtNcallback, readCallback, (XtPointer)fat);
  494.  
  495.     XtAddCallback(sizeMenu[SZ_N1].widget,
  496.             XtNcallback, sizeCallback, (XtPointer)info);
  497.     XtAddCallback(sizeMenu[SZ_N2].widget,
  498.             XtNcallback, sizeCallback, (XtPointer)info);
  499.     XtAddCallback(sizeMenu[SZ_N3].widget,
  500.             XtNcallback, sizeCallback, (XtPointer)info);
  501.     XtAddCallback(sizeMenu[SZ_N4].widget,
  502.             XtNcallback, sizeCallback, (XtPointer)info);
  503.     XtAddCallback(sizeMenu[SZ_N5].widget,
  504.             XtNcallback, sizeCallback, (XtPointer)info);
  505.     XtAddCallback(sizeMenu[SZ_N6].widget,
  506.             XtNcallback, sizeChoiceCallback, (XtPointer)info);
  507.     XtAddCallback(imageMenu[0].widget,
  508.             XtNcallback, gridCallback, (XtPointer)info);
  509.     
  510.     info->sizeChecks[0] = sizeMenu[SZ_N1].widget;
  511.     info->sizeChecks[1] = sizeMenu[SZ_N2].widget;
  512.     info->sizeChecks[2] = sizeMenu[SZ_N3].widget;
  513.     info->sizeChecks[3] = sizeMenu[SZ_N4].widget;
  514.     info->sizeChecks[4] = sizeMenu[SZ_N5].widget;
  515.     info->sizeChecks[5] = sizeMenu[SZ_N6].widget;
  516.     
  517.     XtVaGetValues(info->fat, XtNdrawWidth, &width, XtNdrawHeight, &height, NULL);
  518.     cac(info, width, height);
  519.  
  520.     XtAddCallback(okButton, XtNcallback, 
  521.             (XtCallbackProc)buttonCallback, (XtPointer)info);
  522.     XtAddCallback(cancelButton, XtNcallback, 
  523.             (XtCallbackProc)closeCallback, (XtPointer)info);
  524.     AddDestroyCallback(shell, (void (*)(Widget, void *, XEvent *))closeCallback, info);
  525.     XtAddCallback(grabButton, XtNcallback, 
  526.             (XtCallbackProc)grabCallback, (XtPointer)info);
  527.     XtAddCallback(matchButton, XtNcallback, 
  528.             (XtCallbackProc)matchCallback, (XtPointer)info);
  529.  
  530.     XtPopup(shell, XtGrabNone);
  531.  
  532.     activePixel(info, 0);
  533.  
  534.     GraphicAdd(fat);
  535.     GraphicAdd(norm);
  536. }
  537.